package com.yiren.dbaa.module.practice_set.map.api.impl;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Polygon;
import com.yiren.backstage.currency.bean.CarStateBean;
import com.yiren.backstage.currency.bean.PointBean;
import com.yiren.backstage.currency.entity.TrajectoryPointEntity;
import com.yiren.backstage.currency.enums.CarStateValueEnum;
import com.yiren.dbaa.constant.NumberConstant;
import com.yiren.dbaa.currency.model.TrajectVariableModel;
import com.yiren.dbaa.module.practice_set.map.api.IJtsJudge;
import com.yiren.dbaa.util.JtsUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by WANGRONGXIANG
 * on 2022/4/21
 * Describe 获取高精度评判状态实现类
 */
public class JtsJudgeImpl implements IJtsJudge {

    private JtsUtils jtsUtils;

    //人行横道参数
    private float initAngle = 0;  //车辆与人行横道相交时候的初始角度
    //后溜参数
    private boolean isCheckBack = false;  //检测后溜
    private double lastBackDistance = 0;  //保存上一次后溜的距离
    private double startFrontDistance = 0;//后溜时开始前进的距离
    private PointBean centerPoint;        //上次0点和1点中点坐标
    //变道参数
    private int zzbdHeadPointChoose = 3;  //自主变道车头点位选择(1:2、24点 2:3、23点 3:24、2点)
    private boolean isRotateValue = false;//与虚线相交旋转方向是否赋值
    private boolean isLeftRotate = false; //车辆是否是向左转
    private long lanePassTime = 0;        //检测到变道通过的时间
    //获取边线距离参数
    private int collectLineMode = 1;      //采集线的方式(1:实线采集内边，虚线采集中间  2:全部采集中心点(因采集线时是采集的中间 需减去二分之一线宽))

    public JtsJudgeImpl() {
        jtsUtils = new JtsUtils();
    }

    @Override
    public void checkCarPressSLine(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setPressSLine(CarStateValueEnum.NO_DETECT);
        } else {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            boolean isPressSLine = false;  //是否压实线
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() < 2) continue;
                LineString lineString = jtsUtils.createLineByPoints(pds);
                if (null != lineString) {
                    isPressSLine = jtsUtils.intersects(lineString, model.getCarLineString()) || jtsUtils.intersects(lineString, model.getWheelLineString());
                    if (isPressSLine) break;
                }
            }
            CarStateBean.getInstance().setPressSLine(isPressSLine ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
        }
    }

    @Override
    public void checkCarPressXLine(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setPressSLine(CarStateValueEnum.NO_DETECT);
        } else {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            boolean isPressXLine = false;  //是否压实线
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() < 2) continue;
                LineString lineString = jtsUtils.createLineByPoints(pds);
                if (null != lineString) {
                    isPressXLine = jtsUtils.intersects(lineString, model.getCarLineString()) || jtsUtils.intersects(lineString, model.getWheelLineString());
                    if (isPressXLine) break;
                }
            }
            CarStateBean.getInstance().setPressXLine(isPressXLine ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
        }
    }

    @Override
    public void checkRxhdRelative(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setCarTopProhibitRegion(CarStateValueEnum.NO_DETECT);
            CarStateBean.getInstance().setRxhdxCarPass(CarStateValueEnum.NO_DETECT);
            CarStateBean.getInstance().setRxhdxTurnRound(CarStateValueEnum.NO_DETECT);
        } else {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            boolean isIntersectsRxhd = false;  //是否与人行横道相交
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() != 4) continue;
                Polygon polygon = jtsUtils.createPolygonByPoints(pds);
                if (null != polygon) {
                    isIntersectsRxhd = jtsUtils.intersects(polygon, model.getCarLineString()) || jtsUtils.intersects(polygon, model.getWheelLineString());
                    if (isIntersectsRxhd) break;
                }
            }
            CarStateBean.getInstance().setRxhdxCarPass(isIntersectsRxhd ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
            //人形横道通过监控状态检测
            if (CarStateBean.getInstance().getSpeed() > NumberConstant.CAR_STOP_SPEED) {
                if (isIntersectsRxhd) {
                    if (initAngle == 0) {  //计算车辆与人行横道相交时候的角度
                        initAngle = CarStateBean.getInstance().getNsbsAngleDiff();
                    }
                    if (Math.abs(CarStateBean.getInstance().getNsbsAngleDiff() - initAngle) > 45) {
                        //如果在人行横道上面陀螺仪实时角度 变化大于45度，则认为在人行横道上掉头
                        CarStateBean.getInstance().setRxhdxTurnRound(CarStateValueEnum.PASS);
                    }
                } else {
                    initAngle = 0;
                    CarStateBean.getInstance().setRxhdxTurnRound(CarStateValueEnum.NO_DETECT);
                }
            }
        }
    }

    @Override
    public void checkCarPassTzx(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setTzxCarPass(CarStateValueEnum.NO_DETECT);
        } else {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            boolean isCarPassTzx = false;  //车辆是否通过停止线
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() != 2) continue;
                LineString lineString = jtsUtils.createLineByPoints(pds);
                if (null != lineString) {
                    isCarPassTzx = jtsUtils.intersects(lineString, model.getCarLineString()) || jtsUtils.intersects(lineString, model.getWheelLineString());
                    if (isCarPassTzx) break;
                }
            }
            CarStateBean.getInstance().setTzxCarPass(isCarPassTzx ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
        }
    }

    @Override
    public void checkCarStopJtqy(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setCarTopProhibitRegion(CarStateValueEnum.NO_DETECT);
        } else if (CarStateBean.getInstance().getSpeed() > NumberConstant.CAR_STOP_SPEED) {
            CarStateBean.getInstance().setCarTopProhibitRegion(CarStateValueEnum.NO_PASS);
        } else {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            boolean isCarStopJtqy = false;  //车辆是否停在禁停区域
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() < 2) continue;
                Geometry jtqy = pds.size() == 2 ? jtsUtils.createLineByPoints(pds) : jtsUtils.createPolygonByPoints(pds);
                if (null != jtqy) {
                    isCarStopJtqy = jtsUtils.intersects(jtqy, model.getCarLineString()) || jtsUtils.intersects(jtqy, model.getWheelLineString());
                    if (isCarStopJtqy) break;
                }
            }
            CarStateBean.getInstance().setCarTopProhibitRegion(isCarStopJtqy ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
        }
    }

    @Override
    public void checkCarPressZxq(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setPressZxq(CarStateValueEnum.NO_DETECT);
        } else {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            boolean isPressZxq = false;  //是否压中心圈
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() != 2) continue;
                PointBean onePoint = pds.get(0).getPoint();
                PointBean twoPoint = pds.get(1).getPoint();
                //计算两点距离
                float radius = (float) Math.sqrt(Math.abs((onePoint.getX() - twoPoint.getX()) * (onePoint.getX() - twoPoint.getX()) + (onePoint.getY() - twoPoint.getY()) * (onePoint.getY() - twoPoint.getY())));
                Polygon zxq = jtsUtils.createCircle(onePoint.getX(), onePoint.getY(), radius);
                if (null != zxq) {
                    isPressZxq = jtsUtils.intersects(zxq, model.getCarLineString()) || jtsUtils.intersects(zxq, model.getWheelLineString());
                    if (isPressZxq) break;
                }
            }
            CarStateBean.getInstance().setPressZxq(isPressZxq ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
        }
    }

    @Override
    public void checkCarPressQbkb(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setPressQbkbFullLine(CarStateValueEnum.NO_DETECT);
        } else {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            boolean isPressQbkb = false;  //是否压起步靠边实线
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() < 2) continue;
                LineString lineString = jtsUtils.createLineByPoints(pds);
                if (null != lineString) {
                    isPressQbkb = jtsUtils.intersects(model.getCarLineString(), lineString) || jtsUtils.intersects(model.getWheelLineString(), lineString);
                    if (isPressQbkb) break;
                }
            }
            CarStateBean.getInstance().setPressQbkbFullLine(isPressQbkb ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
        }
    }

    @Override
    public void checkCarPressXsjt(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.NO_PASS);
            return;
        }
        Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
        boolean isPressXsjt = false;
        int trajectType = 0;
        while (it.hasNext()) {
            Map.Entry m = it.next();
            List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
            if (null == pds || pds.size() != 2) continue;
            LineString lineString = jtsUtils.createLineByPoints(pds);
            if (null != lineString) {
                isPressXsjt = jtsUtils.intersects(model.getCarLineString(), lineString) || jtsUtils.intersects(model.getWheelLineString(), lineString);
                if (isPressXsjt) {
                    trajectType = pds.get(0).getTrajectory().getTrajectoryType();
                    break;
                }
            }
        }
        if (isPressXsjt) {
            switch (trajectType) {
                case 10:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZX_BS);
                    break;
                case 11:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.YZ_BS);
                    break;
                case 12:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZZ_BS);
                    break;
                case 13:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.DT_BS);
                    break;
                case 14:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZXZZ_BS);
                    break;
                case 15:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZXYZ_BS);
                    break;
                case 16:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZXDT_BS);
                    break;
                case 17:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZZDT_BS);
                    break;
                case 18:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZXZZDT_BS);
                    break;
                case 21:
                    CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.ZYZ_BS);
                    break;
                default:
                    break;
            }
        } else {
            CarStateBean.getInstance().setCarPressXsjt(CarStateValueEnum.NO_PASS);
        }
    }

    @Override
    public void checkCarIntersectScqy(HashMap<String, List<TrajectoryPointEntity>> map, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == model.getCarLineString() || null == model.getWheelLineString()) {
            CarStateBean.getInstance().setCarIntersectScqy(CarStateValueEnum.NO_PASS);
            return;
        }
        Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
        boolean isIntersectsScqy = false;  //是否与刹车区域相交
        while (it.hasNext()) {
            Map.Entry m = it.next();
            List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
            if (null == pds || pds.size() != 4) continue;
            //车头过了12点连线踩刹车不算
            LineString lineString12 = jtsUtils.createLine(pds.get(0).getPoint(), pds.get(1).getPoint());
            Polygon polygon = jtsUtils.createPolygonByPoints(pds);
            isIntersectsScqy = (jtsUtils.intersects(model.getCarLineString(), polygon) || jtsUtils.intersects(model.getWheelLineString(), polygon)) && !jtsUtils.intersects(lineString12, model.getCarLineString()) && !jtsUtils.intersects(lineString12, model.getWheelLineString());
            if (isIntersectsScqy) break;
        }
        //与刹车区域相交监控状态检测
        CarStateBean.getInstance().setCarIntersectScqy(isIntersectsScqy ? CarStateValueEnum.PASS : CarStateValueEnum.NO_PASS);
    }

    @Override
    public void checkZxqLeftTurn(float x, float y, double radius, LineString carLineString, List<PointBean> carPoints) {
        //当前为中心圈左侧转弯检测
        //车辆行驶到中心圈半径3米范围内，执行中心圈左转判断
        if (jtsUtils.intersects(carLineString, jtsUtils.createCircle(x, y, radius + 3))) {
            PointBean circleCenterPoint = new PointBean(x, y);
            PointBean carCenterPoint = new PointBean((carPoints.get(1).getX() + carPoints.get(13).getX()) / 2, (carPoints.get(1).getY() + carPoints.get(13).getY()) / 2);
            boolean lineRotateDirection = jtsUtils.getLineRotateDirection(circleCenterPoint, carCenterPoint, carPoints.get(13), carPoints.get(1));
            if (lineRotateDirection) { //如果出现车身线在中心圈中点与车身中点连线的逆时针方向，则说明是从中心点右侧通过，错误
                CarStateBean.getInstance().setZxqRightTurnCircle(CarStateValueEnum.PASS);
            } else {
                CarStateBean.getInstance().setZxqRightTurnCircle(CarStateValueEnum.NO_PASS);
            }
        } else {
            CarStateBean.getInstance().setZxqRightTurnCircle(CarStateValueEnum.NO_DETECT);
        }
    }

    @Override
    public void checkBackDistance(List<PointBean> carPoints) {
        if (!isCheckBack) {
            startFrontDistance = 0;
            lastBackDistance = 0;
            centerPoint = null;
            CarStateBean.getInstance().setBackSkateDistance(0);
        }
        if (CarStateBean.getInstance().getSpeed() < NumberConstant.CAR_STOP_SPEED) {
            isCheckBack = true;
        }
        if (isCheckBack) {
            PointBean zeroPoint = carPoints.get(0);
            PointBean onePoint = carPoints.get(1);
            if (null == centerPoint) {
                centerPoint = new PointBean((zeroPoint.getX() + onePoint.getX()) / 2, (zeroPoint.getY() + onePoint.getY()) / 2);
            }
            double currentZeroToCenterPointDistance = Math.sqrt(Math.abs((zeroPoint.getX() - centerPoint.getX()) * (zeroPoint.getX() - centerPoint.getX()) + (zeroPoint.getY() - centerPoint.getY()) * (zeroPoint.getY() - centerPoint.getY())));
            double currentOneToCenterPointDistance = Math.sqrt(Math.abs((onePoint.getX() - centerPoint.getX()) * (onePoint.getX() - centerPoint.getX()) + (onePoint.getY() - centerPoint.getY()) * (onePoint.getY() - centerPoint.getY())));
            if ((currentZeroToCenterPointDistance - currentOneToCenterPointDistance) > 0) { //后溜
                float centerX = (zeroPoint.getX() + onePoint.getX()) / 2;
                float centerY = (zeroPoint.getY() + onePoint.getY()) / 2;
                double distance = Math.sqrt(Math.abs((centerX - centerPoint.getX()) * (centerX - centerPoint.getX()) + (centerY - centerPoint.getY()) * (centerY - centerPoint.getY()))) * 100;
                if (distance > lastBackDistance) { //后溜距离越来越大
                    startFrontDistance = 0;
                    CarStateBean.getInstance().setBackSkateDistance((int) distance);
                } else {  //后溜中开始前进
                    if (startFrontDistance == 0) {
                        startFrontDistance = distance;
                    }
                    if ((distance - startFrontDistance) < -5 || CarStateBean.getInstance().getSpeed() > 10) {
                        isCheckBack = false;
                        CarStateBean.getInstance().setBackSkateDistance(0);
                        centerPoint = null;
                    }
                }
                lastBackDistance = distance;
            } else { //前进
                isCheckBack = false;
                CarStateBean.getInstance().setBackSkateDistance(0);
                centerPoint = null;
            }
        }
    }

    @Override
    public void checkCarChangeLane(HashMap<String, List<TrajectoryPointEntity>> map, List<PointBean> carPoints, TrajectVariableModel model) {
        if (null == map || map.size() == 0 || null == carPoints || carPoints.size() != 33) {
            CarStateBean.getInstance().setCarLeftChangeLane(CarStateValueEnum.NO_DETECT);
            CarStateBean.getInstance().setCarRightChangeLane(CarStateValueEnum.NO_DETECT);
            return;
        }
        if (CarStateBean.getInstance().getPressXLine() == CarStateValueEnum.PASS) {
            //压虚线后才检测变道
            PointBean leftPoint = null;   //左变道标识点
            PointBean rightPoint = null;  //右变道标识点
            if (zzbdHeadPointChoose == 1) {
                leftPoint = carPoints.get(2);
                rightPoint = carPoints.get(24);
            } else if (zzbdHeadPointChoose == 2) {
                leftPoint = carPoints.get(3);
                rightPoint = carPoints.get(23);
            } else if (zzbdHeadPointChoose == 3) {
                leftPoint = carPoints.get(24);
                rightPoint = carPoints.get(2);
            }
            int direction = 0;            //车辆压线的线段采集方向
            boolean isLeftPass = false;   //左变道标识点是否通过虚线
            boolean isRightPass = false;  //右变道标识点是否通过虚线
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() < 2) continue;
                PointBean onePoint = null, twoPoint = null;  //虚线上与车辆相交的两个点
                //获取到与车辆相交的轨迹上的点
                if (null != model.getCarLineString() && jtsUtils.intersects(jtsUtils.createLineByPoints(pds), model.getCarLineString())) {
                    //获取到轨迹上相交的两点
                    for (int i = 0; i < pds.size(); i++) {
                        if (i < pds.size() - 1) {
                            if (jtsUtils.intersects(jtsUtils.createLine(pds.get(i).getPoint(), pds.get(i + 1).getPoint()), model.getCarLineString())) {
                                onePoint = pds.get(i).getPoint();
                                twoPoint = pds.get(i + 1).getPoint();
                                break;
                            }
                        }
                    }
                    if (onePoint != null && twoPoint != null) {
                        if (!isRotateValue) {
                            isRotateValue = true;
                            isLeftRotate = jtsUtils.getLineRotateDirection(onePoint, twoPoint, carPoints.get(13), carPoints.get(1));
                        }
                        float angle = jtsUtils.angleBetween2Lines(onePoint, twoPoint, carPoints.get(13), carPoints.get(1));
                        //车辆方向与线段方向之间的夹角在第二、三象限则为逆向，在一、四象限为正向（解决一共两车道，逆向压中间虚线变道不检测的问题）
                        direction = (angle >= 90 && angle <= 270) ? 2 : 1;
                        isLeftPass = jtsUtils.pointIsTrajectoryLeft(leftPoint, onePoint, twoPoint);
                        isRightPass = !jtsUtils.pointIsTrajectoryLeft(rightPoint, onePoint, twoPoint);
                    }
                    break;
                }
            }
            if (direction == 0 || direction == 1) {
                if (isLeftRotate) {
                    if (isLeftPass) {
                        CarStateBean.getInstance().setCarLeftChangeLane(CarStateValueEnum.PASS);
                        if (lanePassTime == 0) {
                            lanePassTime = System.currentTimeMillis();
                        }
                    } else {  //增加变道通过维持时间1S，防止通过状态被覆盖导致编译器没有取到变道通过的状态，下同
                        if (lanePassTime != 0 && System.currentTimeMillis() - lanePassTime > 1000) {
                            CarStateBean.getInstance().setCarLeftChangeLane(CarStateValueEnum.NO_PASS);
                            lanePassTime = 0;
                        }
                    }
                } else {
                    if (isRightPass) {
                        CarStateBean.getInstance().setCarRightChangeLane(CarStateValueEnum.PASS);
                        if (lanePassTime == 0) {
                            lanePassTime = System.currentTimeMillis();
                        }
                    } else {
                        if (lanePassTime != 0 && System.currentTimeMillis() - lanePassTime > 1000) {
                            CarStateBean.getInstance().setCarRightChangeLane(CarStateValueEnum.NO_PASS);
                            lanePassTime = 0;
                        }
                    }
                }
            } else {
                if (!isLeftRotate) {
                    if (!isLeftPass) {
                        CarStateBean.getInstance().setCarLeftChangeLane(CarStateValueEnum.PASS);
                        if (lanePassTime == 0) {
                            lanePassTime = System.currentTimeMillis();
                        }
                    } else {
                        if (lanePassTime != 0 && System.currentTimeMillis() - lanePassTime > 1000) {
                            CarStateBean.getInstance().setCarLeftChangeLane(CarStateValueEnum.NO_PASS);
                            lanePassTime = 0;
                        }
                    }
                } else {
                    if (!isRightPass) {
                        CarStateBean.getInstance().setCarRightChangeLane(CarStateValueEnum.PASS);
                        if (lanePassTime == 0) {
                            lanePassTime = System.currentTimeMillis();
                        }
                    } else {
                        if (lanePassTime != 0 && System.currentTimeMillis() - lanePassTime > 1000) {
                            CarStateBean.getInstance().setCarRightChangeLane(CarStateValueEnum.NO_PASS);
                            lanePassTime = 0;
                        }
                    }
                }
            }
        } else {
            isRotateValue = false;
            if (lanePassTime != 0 && System.currentTimeMillis() - lanePassTime > 1000) {
                CarStateBean.getInstance().setCarLeftChangeLane(CarStateValueEnum.NO_PASS);
                CarStateBean.getInstance().setCarRightChangeLane(CarStateValueEnum.NO_PASS);
                lanePassTime = 0;
            }
        }
    }

    @Override
    public void checkCarLaneDistance(HashMap<String, List<TrajectoryPointEntity>> map, List<PointBean> carPoints, TrajectVariableModel model) {
        double headLeftMinDistance = 9999;   //25点到左边线的距离
        double endLeftMinDistance = 9999;    //29点到左边线的距离
        double headRightMinDistance = 9999;  //27点到右边线的距离
        double endRightMinDistance = 9999;   //31点到右边线的距离
        PointBean[] headLeftMinPoints = {null, null}; //距离25点最近的两个轨迹点位
        PointBean[] endLeftMinPoints = {null, null};  //距离29点最近的两个轨迹点位
        PointBean[] headRightMinPoints = {null, null};//距离27点最近的两个轨迹点位
        PointBean[] endRightMinPoints = {null, null}; //距离31点最近的两个轨迹点位
        if (null != map && map.size() != 0 && null != carPoints && carPoints.size() == 33) {
            Iterator<Map.Entry<String, List<TrajectoryPointEntity>>> it = map.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry m = it.next();
                List<TrajectoryPointEntity> pds = (List<TrajectoryPointEntity>) m.getValue();
                if (null == pds || pds.size() < 2) continue;
                double lineWidth = ((double) pds.get(0).getTrajectory().getLineWidth() / 2.0) / 100.0;
                for (int i = 0; i < pds.size() - 1; i++) {
                    PointBean pointOne = pds.get(i).getPoint();
                    PointBean pointTwo = pds.get(i + 1).getPoint();
                    LineString bxLineString = jtsUtils.createLine(pointOne, pointTwo);
                    float angle = jtsUtils.angleBetween2Lines(pointOne, pointTwo, carPoints.get(13), carPoints.get(1));
                    //车辆方向与线段方向之间的夹角在第二、三象限则为逆向，在一、四象限为正向（解决一共两车道，逆向压中间虚线变道不检测的问题）
                    int collectDirection = (angle >= 90 && angle <= 270) ? 2 : 1;
                    boolean isLeft = jtsUtils.pointIsTrajectoryLeft(carPoints.get(1), pointOne, pointOne);
                    if (((collectDirection == 0 || collectDirection == 1) && isLeft) || (collectDirection == 2 && !isLeft)) {
                        double headLeftDistance, endLeftDistance, headRightDistance, endRightDistance;
                        if (collectLineMode == 1) {  //实线采集内边，虚线采集中间
                            headLeftDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(25)));
                            endLeftDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(29)));
                            headRightDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(27)));
                            endRightDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(31)));
                        } else {   //全部采集中心点
                            //因采集线时是采集的中间 需减去二分之一线宽
                            headLeftDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(25))) - lineWidth;
                            endLeftDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(29))) - lineWidth;
                            headRightDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(27))) - lineWidth;
                            endRightDistance = jtsUtils.distanceGeo(bxLineString, jtsUtils.createGeomPoint(carPoints.get(31))) - lineWidth;
                        }
                        if (headLeftDistance < headLeftMinDistance) {
                            headLeftMinDistance = headLeftDistance;
                            headLeftMinPoints[0] = collectDirection == 2 ? pointTwo : pointOne;
                            headLeftMinPoints[1] = collectDirection == 2 ? pointOne : pointTwo;
                        }
                        if (endLeftDistance < endLeftMinDistance) {
                            endLeftMinDistance = endLeftDistance;
                            endLeftMinPoints[0] = collectDirection == 2 ? pointTwo : pointOne;
                            endLeftMinPoints[1] = collectDirection == 2 ? pointOne : pointTwo;
                        }
                        if (headRightDistance < headRightMinDistance) {
                            headRightMinDistance = headRightDistance;
                            headRightMinPoints[0] = collectDirection == 2 ? pointTwo : pointOne;
                            headRightMinPoints[1] = collectDirection == 2 ? pointOne : pointTwo;
                        }
                        if (endRightDistance < endRightMinDistance) {
                            endRightMinDistance = endRightDistance;
                            endRightMinPoints[0] = collectDirection == 2 ? pointTwo : pointOne;
                            endRightMinPoints[1] = collectDirection == 2 ? pointOne : pointTwo;
                        }
                    }
                }
            }
            //车头25点距离边线的距离
            if (headLeftMinDistance > NumberConstant.CAR_LANE_DISTANCE) {
                CarStateBean.getInstance().setLeftFrontDistance(9999);
            } else {
                boolean point25IsLeft = jtsUtils.pointIsTrajectoryLeft(carPoints.get(25), headLeftMinPoints[0], headLeftMinPoints[1]);
                CarStateBean.getInstance().setLeftFrontDistance((int) ((point25IsLeft ? -headLeftMinDistance : headLeftMinDistance) * 100));
            }
            //车尾29点距离边线的距离
            if (endLeftMinDistance > NumberConstant.CAR_LANE_DISTANCE) {
                CarStateBean.getInstance().setLeftBackDistance(9999);
            } else {
                boolean point29IsLeft = jtsUtils.pointIsTrajectoryLeft(carPoints.get(29), endLeftMinPoints[0], endLeftMinPoints[1]);
                CarStateBean.getInstance().setLeftBackDistance((int) ((point29IsLeft ? -endLeftMinDistance : endLeftMinDistance) * 100));
            }
            //车头27点距离边线的距离
            if (headRightMinDistance > NumberConstant.CAR_LANE_DISTANCE) {
                CarStateBean.getInstance().setRightFrontDistance(9999);
            } else {
                boolean point27IsLeft = jtsUtils.pointIsTrajectoryLeft(carPoints.get(27), headRightMinPoints[0], headRightMinPoints[1]);
                CarStateBean.getInstance().setRightFrontDistance((int) ((point27IsLeft ? headRightMinDistance : -headRightMinDistance) * 100));
            }
            //车尾31点距离边线的距离
            if (endRightMinDistance > NumberConstant.CAR_LANE_DISTANCE) {
                CarStateBean.getInstance().setRightBackDistance(9999);
            } else {
                boolean point31IsLeft = jtsUtils.pointIsTrajectoryLeft(carPoints.get(31), endRightMinPoints[0], endRightMinPoints[1]);
                CarStateBean.getInstance().setRightBackDistance((int) ((point31IsLeft ? endRightMinDistance : -endRightMinDistance) * 100));
            }
        }

    }
}
